home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
strategy
/
xpuzzles.3
/
xpuzzles
/
xpuzzles-5.3.1
/
xoct
/
xmoct.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-07
|
19KB
|
666 lines
/*
# MOTIF-BASED OCTAHEDRON
#
# xmoct.c
#
###
#
# Copyright (c) 1993 - 96 David Albert Bagley, bagleyd@hertz.njit.edu
#
# All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and
# that both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of the author not be
# used in advertising or publicity pertaining to distribution of the
# software without specific, written prior permission.
#
# This program is distributed in the hope that it will be "useful",
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
*/
/*
Version 5: 95/10/04 Xt/Motif
Version 4: 94/05/31 Xt
Version 3: 93/04/01 Motif
Version 2: 92/02/01 XView
Version 1: 91/06/10 SunView
*/
#include <stdlib.h>
#include <stdio.h>
#ifdef VMS
#include <unixlib.h>
#define getlogin cuserid
#else
#ifndef apollo
#include <unistd.h>
#endif
#endif
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/cursorfont.h>
#include <Xm/PanedW.h>
#include <Xm/RowColumn.h>
#include <Xm/Label.h>
#include <Xm/LabelG.h>
#include <Xm/Scale.h>
#include <Xm/ToggleB.h>
#include <Xm/ToggleBG.h>
#include "Oct.h"
#include "oct.xbm"
#include "mouse-l.xbm"
#include "mouse-r.xbm"
#ifndef SCOREFILE
#define SCOREFILE "/usr/games/lib/oct.scores"
#endif
/* The following are in OctP.h also */
#define MINOCTAS 1
#define PERIOD3 3
#define PERIOD4 4
#define BOTH 5
#define MAXMODES 3
#define MAXOCTAS 6
#define MAXRECORD 32767
static void Initialize();
static void CallbackOct();
static void PrintRecord();
static int HandleSolved();
static void ReadRecords();
static void WriteRecords();
static void OctaSlider();
static void ModeToggle();
static void OrientToggle();
static void StickyToggle();
static void PracticeToggle();
static void motif_printf();
static Arg arg[5];
static Widget moves, record, message, oct, modes[MAXMODES],
orientSwitch, stickySwitch, practiceSwitch, octas;
static int octRecord[MAXMODES][2][MAXOCTAS - MINOCTAS + 2], movesDsp = 0;
static int oldSize;
static char messageDsp[128] = "Welcome";
static char *modeString[] = {
"Period 3", "Period 4", "Both"
};
static void Usage()
{
(void) fprintf(stderr, "usage: xmoct\n");
(void) fprintf(stderr,
"\t[-geometry [{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]]\n");
(void) fprintf(stderr,
"\t[-display [{host}]:[{vs}]] [-fg {color}] [-bg {color}]\n");
(void) fprintf(stderr,
"\t[-{border|bd} {color}] [-mono] [-{size {int} | sticky}]\n");
(void) fprintf(stderr,
"\t[[-{mode {int} | both}] [-[no]orient] [-[no]practice]\n");
(void) fprintf(stderr,
"\t[-face{0|1|2|3|4|5|6|7} {color}]\n");
exit(1);
}
static XrmOptionDescRec options[] = {
{"-fg", "*oct.Foreground", XrmoptionSepArg, NULL},
{"-bg", "*Background", XrmoptionSepArg, NULL},
{"-foreground", "*oct.Foreground", XrmoptionSepArg, NULL},
{"-background", "*Background", XrmoptionSepArg, NULL},
{"-border", "*oct.pieceBorder", XrmoptionSepArg, NULL},
{"-bd", "*oct.pieceBorder", XrmoptionSepArg, NULL},
{"-mono", "*oct.mono", XrmoptionNoArg, "TRUE"},
{"-size", "*oct.size", XrmoptionSepArg, NULL},
{"-sticky", "*oct.sticky", XrmoptionNoArg, "FALSE"},
{"-mode", "*oct.mode", XrmoptionSepArg, NULL},
{"-both", "*oct.mode", XrmoptionNoArg, "4"},
{"-orient", "*oct.orient", XrmoptionNoArg, "TRUE"},
{"-noorient", "*oct.orient", XrmoptionNoArg, "FALSE"},
{"-practice", "*oct.practice", XrmoptionNoArg, "TRUE"},
{"-nopractice", "*oct.practice", XrmoptionNoArg, "FALSE"},
{"-face0", "*oct.faceColor0", XrmoptionSepArg, NULL},
{"-face1", "*oct.faceColor1", XrmoptionSepArg, NULL},
{"-face2", "*oct.faceColor2", XrmoptionSepArg, NULL},
{"-face3", "*oct.faceColor3", XrmoptionSepArg, NULL},
{"-face4", "*oct.faceColor4", XrmoptionSepArg, NULL},
{"-face5", "*oct.faceColor5", XrmoptionSepArg, NULL},
{"-face6", "*oct.faceColor6", XrmoptionSepArg, NULL},
{"-face7", "*oct.faceColor7", XrmoptionSepArg, NULL}
};
int main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel;
Widget panel, panel2, rowcol, rowcol2, rowcol3, rowcol4;
Pixmap mouseLeftCursor, mouseRightCursor;
Pixel fg, bg;
int i;
toplevel = XtInitialize(argv[0], "Oct",
options, XtNumber(options), &argc, argv);
if (argc != 1)
Usage();
XtSetArg(arg[0], XtNiconPixmap,
XCreateBitmapFromData(XtDisplay(toplevel),
RootWindowOfScreen(XtScreen(toplevel)),
(char *) oct_bits, oct_width, oct_height));
XtSetArg(arg[1], XmNkeyboardFocusPolicy, XmPOINTER); /* not XmEXPLICIT */
XtSetValues(toplevel, arg, 2);
panel = XtCreateManagedWidget("panel", xmPanedWindowWidgetClass, toplevel,
NULL, 0);
panel2 = XtVaCreateManagedWidget("panel2", xmPanedWindowWidgetClass, panel,
XmNseparatorOn, False,
XmNsashWidth, 1,
XmNsashHeight, 1,
NULL);
rowcol = XtVaCreateManagedWidget("Rowcol", xmRowColumnWidgetClass, panel2,
XmNnumColumns, 2,
XmNorientation, XmHORIZONTAL,
XmNpacking, XmPACK_COLUMN,
NULL);
XtVaGetValues(rowcol, XmNforeground, &fg, XmNbackground, &bg, NULL);
mouseLeftCursor = XCreatePixmapFromBitmapData(XtDisplay(rowcol),
RootWindowOfScreen(XtScreen(rowcol)), mouse_left_bits,
mouse_left_width, mouse_left_height, fg, bg,
DefaultDepthOfScreen(XtScreen(rowcol)));
mouseRightCursor = XCreatePixmapFromBitmapData(XtDisplay(rowcol),
RootWindowOfScreen(XtScreen(rowcol)), mouse_right_bits,
mouse_right_width, mouse_right_height, fg, bg,
DefaultDepthOfScreen(XtScreen(rowcol)));
XtVaCreateManagedWidget("mouseLeftText", xmLabelGadgetClass, rowcol,
XtVaTypedArg, XmNlabelString, XmRString, "Move", 5, NULL);
XtVaCreateManagedWidget("mouseLeft", xmLabelGadgetClass, rowcol,
XmNlabelType, XmPIXMAP, XmNlabelPixmap, mouseLeftCursor, NULL);
XtVaCreateManagedWidget("mouseRightText", xmLabelGadgetClass, rowcol,
XtVaTypedArg, XmNlabelString, XmRString, "Randomize", 10, NULL);
XtVaCreateManagedWidget("mouseRight", xmLabelGadgetClass, rowcol,
XmNlabelType, XmPIXMAP, XmNlabelPixmap, mouseRightCursor, NULL);
XtVaCreateManagedWidget("CallbackOct", xmLabelGadgetClass, rowcol,
XtVaTypedArg, XmNlabelString, XmRString, "Moves", 6, NULL);
moves = XtVaCreateManagedWidget("0", xmLabelWidgetClass, rowcol, NULL);
XtVaCreateManagedWidget("record_text", xmLabelGadgetClass, rowcol,
XtVaTypedArg, XmNlabelString, XmRString, "Record", 7, NULL);
record = XtVaCreateManagedWidget("0", xmLabelWidgetClass, rowcol, NULL);
rowcol2 = XtVaCreateManagedWidget("Rowcol2", xmRowColumnWidgetClass, panel2,
NULL);
XtVaGetValues(rowcol2, XmNforeground, &fg, XmNbackground, &bg, NULL);
octas = XtVaCreateManagedWidget("octas", xmScaleWidgetClass, rowcol2,
XtVaTypedArg, XmNtitleString, XmRString, "Octas", 6,
XmNminimum, MINOCTAS,
XmNmaximum, MAXOCTAS,
XmNvalue, MINOCTAS,
XmNshowValue, True,
XmNorientation, XmHORIZONTAL,
NULL);
XtAddCallback(octas, XmNvalueChangedCallback, OctaSlider, NULL);
rowcol3 = XtVaCreateManagedWidget("Rowcol", xmRowColumnWidgetClass, rowcol2,
XmNnumColumns, 1,
XmNorientation, XmHORIZONTAL,
XmNpacking, XmPACK_COLUMN,
XmNradioBehavior, True,
NULL);
for (i = 0; i < XtNumber(modeString); i++) {
modes[i] = XtVaCreateManagedWidget(modeString[i],
xmToggleButtonGadgetClass, rowcol3,
XmNradioBehavior, True,
NULL);
XtAddCallback(modes[i], XmNvalueChangedCallback, ModeToggle,
(XtPointer) i);
}
rowcol4 = XtVaCreateManagedWidget("Rowcol", xmRowColumnWidgetClass, rowcol2,
XmNnumColumns, 1,
XmNorientation, XmHORIZONTAL,
XmNpacking, XmPACK_COLUMN,
NULL);
orientSwitch = XtVaCreateManagedWidget ("Orient",
xmToggleButtonWidgetClass, rowcol4,
NULL);
XtAddCallback(orientSwitch, XmNvalueChangedCallback, OrientToggle, NULL);
stickySwitch = XtVaCreateManagedWidget ("Sticky",
xmToggleButtonWidgetClass, rowcol4,
NULL);
XtAddCallback(stickySwitch, XmNvalueChangedCallback, StickyToggle, NULL);
practiceSwitch = XtVaCreateManagedWidget ("Practice",
xmToggleButtonWidgetClass, rowcol4,
NULL);
XtAddCallback(practiceSwitch, XmNvalueChangedCallback, PracticeToggle, NULL);
message = XtVaCreateManagedWidget("Play Oct! (use mouse and keypad)",
xmLabelWidgetClass, rowcol2,
NULL);
oct = XtCreateManagedWidget("oct", octWidgetClass, panel,
NULL, 0);
XtAddCallback(oct, XtNselectCallback, CallbackOct, NULL);
Initialize(oct);
XtRealizeWidget(toplevel);
XGrabButton(XtDisplay(oct), AnyButton, AnyModifier, XtWindow(oct),
TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, XtWindow(oct),
XCreateFontCursor(XtDisplay(oct), XC_crosshair));
XtMainLoop();
#ifdef VMS
return 1;
#else
return 0;
#endif
}
static void Initialize(w)
Widget w;
{
int size, mode;
Boolean orient, sticky, practice;
XtVaSetValues(w,
XtNstart, FALSE,
NULL);
XtVaGetValues(w,
XtNsize, &size,
XtNmode, &mode,
XtNorient, &orient,
XtNsticky, &sticky,
XtNpractice, &practice,
NULL);
if (size <= MAXOCTAS)
XmScaleSetValue(octas, size);
XmToggleButtonSetState(modes[mode - PERIOD3], True, False);
XmToggleButtonSetState(orientSwitch, orient, True);
XmToggleButtonSetState(stickySwitch, sticky, True);
XmToggleButtonSetState(practiceSwitch, practice, True);
ReadRecords();
PrintRecord(size, mode, orient, sticky, practice);
oldSize = size;
}
static void CallbackOct(w, clientData, callData)
Widget w;
caddr_t clientData;
octCallbackStruct *callData;
{
int size, mode;
Boolean orient, sticky, practice, start;
XtVaGetValues(w,
XtNsize, &size,
XtNmode, &mode,
XtNorient, &orient,
XtNsticky, &sticky,
XtNpractice, &practice,
XtNstart, &start,
NULL);
(void) strcpy(messageDsp, "");
switch (callData->reason) {
case OCT_RESTORE:
if (practice)
motif_printf(record, "practice");
movesDsp = 0;
break;
case OCT_RESET:
movesDsp = 0;
break;
case OCT_AMBIGUOUS:
(void) strcpy(messageDsp, "Ambiguous move");
break;
case OCT_ILLEGAL:
if (practice || start)
(void) strcpy(messageDsp, "Illegal move");
else
(void) strcpy(messageDsp, "Randomize to start");
break;
case OCT_MOVED:
movesDsp++;
XtSetArg(arg[0], XtNstart, TRUE);
XtSetValues(w, arg, 1);
break;
case OCT_CONTROL:
return;
case OCT_SOLVED:
if (practice)
movesDsp = 0;
else {
if (HandleSolved(movesDsp, size, mode, orient, sticky))
(void) sprintf(messageDsp, "Congratulations %s!!", getlogin());
else
(void) strcpy(messageDsp, "Solved!");
}
XtSetArg(arg[0], XtNstart, FALSE);
XtSetValues(w, arg, 1);
break;
case OCT_PRACTICE:
movesDsp = 0;
practice = !practice;
if (!practice)
(void) strcpy(messageDsp, "Randomize to start");
PrintRecord(size, mode, orient, sticky, practice);
XtSetArg(arg[0], XtNpractice, practice);
XtSetArg(arg[1], XtNstart, FALSE);
XtSetValues(w, arg, 2);
XmToggleButtonSetState(practiceSwitch, practice, True);
break;
case OCT_RANDOMIZE:
movesDsp = 0;
XtSetArg(arg[0], XtNpractice, FALSE);
XtSetArg(arg[1], XtNstart, FALSE);
XtSetValues(w, arg, 2);
break;
case OCT_DEC:
if (!sticky) {
movesDsp = 0;
size--;
oldSize = size;
PrintRecord(size, mode, orient, sticky, practice);
XtSetArg(arg[0], XtNsize, size);
XtSetValues(w, arg, 1);
if (size <= MAXOCTAS)
XmScaleSetValue(octas, size);
}
break;
case OCT_ORIENT:
movesDsp = 0;
orient = !orient;
PrintRecord(size, mode, orient, sticky, practice);
XtSetArg(arg[0], XtNorient, orient);
XtSetValues(w, arg, 1);
XmToggleButtonSetState(orientSwitch, orient, True);
break;
case OCT_INC:
if (!sticky) {
movesDsp = 0;
size++;
oldSize = size;
PrintRecord(size, mode, orient, sticky, practice);
XtSetArg(arg[0], XtNsize, size);
XtSetValues(w, arg, 1);
if (size <= MAXOCTAS)
XmScaleSetValue(octas, size);
}
break;
case OCT_PERIOD3:
case OCT_PERIOD4:
case OCT_BOTH:
movesDsp = 0;
mode = callData->reason - OCT_PERIOD3 + PERIOD3;
PrintRecord(size, mode, orient, sticky, practice);
XtSetArg(arg[0], XtNmode, mode);
XtSetValues(w, arg, 1);
XmToggleButtonSetState(modes[mode - PERIOD3], True, True);
break;
case OCT_STICKY:
movesDsp = 0;
sticky = !sticky;
if (sticky)
size = 4;
else
size = oldSize;
PrintRecord(size, mode, orient, sticky, practice);
XtSetArg(arg[0], XtNsticky, sticky);
XtSetArg(arg[1], XtNsize, size);
XtSetValues(w, arg, 2);
XmToggleButtonSetState(stickySwitch, sticky, True);
break;
case OCT_COMPUTED:
XtSetArg(arg[0], XtNstart, FALSE);
XtSetValues(w, arg, 1);
break;
case OCT_UNDO:
movesDsp--;
XtSetArg(arg[0], XtNstart, TRUE);
XtSetValues(w, arg, 1);
break;
}
motif_printf(message, "%s", messageDsp);
motif_printf(moves, "%d", movesDsp);
}
static void OctaSlider(w, clientData, cbs)
Widget w;
XtPointer clientData;
XmScaleCallbackStruct *cbs;
{
int size = cbs->value, mode;
Boolean orient, sticky, practice;
XtVaGetValues(oct,
XtNsize, &oldSize,
XtNmode, &mode,
XtNorient, &orient,
XtNsticky, &sticky,
XtNpractice, &practice,
NULL);
if (sticky)
XmScaleSetValue(w, oldSize);
else if (oldSize != size) {
XtVaSetValues(oct,
XtNsize, size,
NULL);
oldSize = size;
movesDsp = 0;
motif_printf(moves, "%d", movesDsp);
PrintRecord(size, mode, orient, sticky, practice);
}
}
static void ModeToggle(w, mode, cbs)
Widget w;
int mode;
XmToggleButtonCallbackStruct *cbs;
{
int size;
Boolean orient, sticky, practice;
if (cbs->set) {
XtVaGetValues(oct,
XtNsize, &size,
XtNorient, &orient,
XtNsticky, &sticky,
XtNpractice, &practice,
NULL);
XtVaSetValues(oct,
XtNmode, mode + PERIOD3,
NULL);
movesDsp = 0;
motif_printf(moves, "%d", movesDsp);
PrintRecord(size, mode + PERIOD3, orient, sticky, practice);
}
}
static void OrientToggle(w, clientData, cbs)
Widget w;
XtPointer clientData;
XmToggleButtonCallbackStruct *cbs;
{
int size, mode;
Boolean orient = cbs->set, sticky, practice;
XtVaGetValues(oct,
XtNsize, &size,
XtNmode, &mode,
XtNsticky, &sticky,
XtNpractice, &practice,
NULL);
XtVaSetValues(oct,
XtNorient, orient,
NULL);
movesDsp = 0;
motif_printf(moves, "%d", movesDsp);
PrintRecord(size, mode, orient, sticky, practice);
}
static void StickyToggle(w, clientData, cbs)
Widget w;
XtPointer clientData;
XmToggleButtonCallbackStruct *cbs;
{
int size, mode;
Boolean orient, sticky = cbs->set, practice;
XtVaGetValues(oct,
XtNsize, &size,
XtNmode, &mode,
XtNorient, &orient,
XtNpractice, &practice,
NULL);
XtVaSetValues(oct,
XtNsticky, sticky,
NULL);
if ((sticky && size != 4) || (!sticky && oldSize != 4)) {
if (sticky)
size = 4;
else
size = oldSize;
if (size <= MAXOCTAS)
XmScaleSetValue(octas, size);
XtVaSetValues(oct,
XtNsize, size,
NULL);
}
movesDsp = 0;
motif_printf(moves, "%d", movesDsp);
PrintRecord(size, mode, orient, sticky, practice);
}
static void PracticeToggle(w, clientData, cbs)
Widget w;
XtPointer clientData;
XmToggleButtonCallbackStruct *cbs;
{
int size, mode;
Boolean orient, sticky, practice = cbs->set;
XtVaSetValues(oct,
XtNpractice, practice,
XtNstart, FALSE,
NULL);
XtVaGetValues(oct,
XtNsize, &size,
XtNmode, &mode,
XtNorient, &orient,
XtNsticky, &sticky,
NULL);
movesDsp = 0;
motif_printf(moves, "%d", movesDsp);
if (!practice)
(void) strcpy(messageDsp, "Randomize to start");
PrintRecord(size, mode, orient, sticky, practice);
}
static void PrintRecord(size, mode, orient, sticky, practice)
int size, mode;
Boolean orient, sticky, practice;
{
int i = mode - PERIOD3;
int j = (orient) ? 1 : 0;
int k = (sticky) ? MAXOCTAS - MINOCTAS + 1 : size - MINOCTAS;
if (practice)
motif_printf(record, "practice");
else if (!sticky && size > MAXOCTAS)
motif_printf(record, "NOT RECORDED");
else if (octRecord[i][j][k] >= MAXRECORD)
motif_printf(record, "NEVER");
else
motif_printf(record, "%d", octRecord[i][j][k]);
}
static int HandleSolved(counter, size, mode, orient, sticky)
int counter, size, mode;
Boolean orient, sticky;
{
int i = mode - PERIOD3;
int j = (orient) ? 1 : 0;
int k = (sticky) ? MAXOCTAS - MINOCTAS + 1 : size - MINOCTAS;
if ((sticky || size <= MAXOCTAS) && counter < octRecord[i][j][k]) {
octRecord[i][j][k] = counter;
if ((size < 2 && mode != PERIOD4) || (size < 4 && mode == PERIOD4) ||
(orient && (octRecord[i][j][k] < octRecord[i][!j][k])))
octRecord[i][!j][k] = counter;
WriteRecords();
PrintRecord(size, mode, orient, sticky, FALSE);
return TRUE;
}
return FALSE;
}
static void ReadRecords()
{
FILE *fp;
int i, n, mode, orient;
for (mode = 0; mode < MAXMODES; mode++)
for (orient = 0; orient < 2; orient++)
for (i = 0; i <= MAXOCTAS - MINOCTAS + 1; i++)
octRecord[mode][orient][i] = MAXRECORD;
if ((fp = fopen(SCOREFILE, "r")) == NULL)
motif_printf(message, "Can not open %s, taking defaults.", SCOREFILE);
else {
for (mode = 0; mode < MAXMODES; mode++)
for (orient = 0; orient < 2; orient++)
for (i = 0; i <= MAXOCTAS - MINOCTAS + 1; i++) {
(void) fscanf(fp, "%d", &n);
octRecord[mode][orient][i] = n;
}
(void) fclose(fp);
}
}
static void WriteRecords()
{
FILE *fp;
int i, mode, orient;
if ((fp = fopen(SCOREFILE, "w")) == NULL)
motif_printf(message, "Can not write to %s.", SCOREFILE);
else {
for (mode = 0; mode < MAXMODES; mode++) {
for (orient = 0; orient < 2; orient++) {
for (i = 0; i <= MAXOCTAS - MINOCTAS + 1; i++)
(void) fprintf(fp, "%d ", octRecord[mode][orient][i]);
(void) fprintf(fp, "\n");
}
(void) fprintf(fp, "\n");
}
(void) fclose(fp);
}
}
#include <varargs.h>
static void motif_printf(va_alist)
va_dcl
{
Widget w;
char *format;
va_list args;
char str[1000];
Arg wargs[10];
XmString xmstr;
va_start(args);
w = va_arg(args, Widget);
if (!XtIsSubclass(w, xmLabelWidgetClass))
XtError("motif_printf() requires a Label Widget");
format = va_arg(args, char *);
(void) vsprintf(str, format, args);
xmstr = XmStringCreateLtoR(str, XmSTRING_DEFAULT_CHARSET);
XtSetArg(wargs[0], XmNlabelString, xmstr);
XtSetValues(w, wargs, 1);
va_end(args);
}